home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Util / Pm-Pz / Protectomat v2.6.cpt / protectomat.2.6 / pmDump.c < prev    next >
Text File  |  1991-10-14  |  11KB  |  450 lines

  1. /*
  2.  * dump protections from an applshare file system to a data file
  3.  * By Aaron Wohl (aw0g+@andrew.cmu.edu)
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <errno.h>
  10. #include <ctype.h>
  11. #include <Packages.h>
  12. #ifdef RUBBISH
  13. not needed since it is in MacHeaders
  14. #include <Files.h>
  15. #endif
  16. #define VER_MAJ (2)
  17. #define VER_MIN (6)
  18.  
  19. #define ROOT_DIR_ID (2L)        /*directory id of the root directory of a volume*/
  20. #define NIL 0L
  21. extern void exit(int);
  22.  
  23. struct {
  24.     FILE *outfile;
  25.     FILE *historyfile;
  26.     long num_desktop_files;    /*number of desktop files found*/
  27.     long num_files;    /*number of directories seen on current volume*/
  28.     long num_dirs;  /*number of directories seen on current volume*/
  29.     long unbacked_files; /*number of files needing to be backed up*/
  30. #define NO_OLDEST (0xffffffffL)
  31.     unsigned long oldest_unbacked; /*write date of oldest unbacked up file*/
  32.     double bytes_needing_saved; /*number of bytes that need to be saved*/
  33. }gl;
  34.  
  35. #define EEXTERN
  36. #include "pmCommon.h"
  37.  
  38.  
  39. void die(char *txt,char *exit_text);
  40. void fatal_error(char *txt,int oserr);
  41.  
  42. /*
  43.  * convert a string to upper case
  44.  */
  45. void upcase(char *s);
  46. void upcase(char *s)
  47. {
  48.     while((*s)!=0) {
  49.         if(islower(*s))
  50.             *s=toupper(*s);
  51.         s++;
  52.     }
  53. }
  54.  
  55.  
  56. /*
  57.  * give a promt and wait for the given reply
  58.  */
  59. void readtoken(char *answer);
  60. void readtoken(char *answer)
  61. {
  62.     char line_buf[ERR_BUF_SIZE];
  63.     while(TRUE) {
  64.         printf("\nEnter this in the log book then type in %s<return> to exit:",answer);
  65.         if(read_line(line_buf,stdin))
  66.             break;
  67.         upcase(line_buf);
  68.         if(strcmp(line_buf,answer)==0)
  69.             break;
  70.     }
  71. }
  72.  
  73. /*
  74.  * close a log file and make sure it was happy
  75.  */
  76. void finish_file(FILE **afile,char *aname);
  77. void finish_file(FILE **afile,char *aname)
  78. {
  79.     FILE *f_to_close=(*afile);
  80.     *afile=0;
  81.     if(f_to_close==0)
  82.         return;
  83.     if(ferror(f_to_close)) {
  84.         char errbuf[ERR_BUF_SIZE];
  85.         sprintf(errbuf,"error writeing to output file '%s'",aname);
  86.         fatal_error(errbuf,0);
  87.     }
  88. }
  89.  
  90. /*
  91.  * fatal error handler
  92.  */
  93. void die(char *txt,char *exit_text)
  94. {
  95.     unsigned long now=time(0L);
  96.     if(gl.outfile!=0) {
  97.         fprintf(gl.outfile,"%s at %s",txt,ctime(&now));
  98.         finish_file(&gl.outfile,"output dump file");
  99.     }
  100.     if(gl.historyfile!=0) {
  101.         fprintf(gl.historyfile,"%s at %s",txt,ctime(&now));
  102.         finish_file(&gl.historyfile,"history log file");
  103.     }
  104.     printf("%s at %s",txt,ctime(&now));
  105.     readtoken(exit_text);
  106.     exit(0);
  107. }
  108.  
  109. /*
  110.  * fatal error handler
  111.  */
  112. void fatal_error(char *txt,int oserr)
  113. {
  114.     char errbuf[ERR_BUF_SIZE];
  115.     sprintf(errbuf,"*** Fatal error:%s, oserr=%d",txt,oserr);
  116.     die(errbuf,"ERROR");
  117. }
  118.  
  119. void file_error(char *fname,char *txt,int oserr);
  120. void file_error(char *fname,char *txt,int oserr)
  121. {
  122.   char err_buf[ERR_BUF_SIZE];
  123.   sprintf(err_buf,"\n?file '%s'\n?%s",fname,txt);
  124.   fatal_error(err_buf,oserr);
  125. }
  126.  
  127. /*
  128.  * str_fname - convert a file name into a unix string
  129.  */
  130. char *str_fname(char *fin);
  131. char *str_fname(fin)
  132. char *fin;
  133. {
  134.     *(fin+1+((*fin)))=0;
  135.     return fin+1;
  136. }
  137.  
  138. /*
  139.  * open the output log file
  140.  */
  141. void open_outfile(void);
  142. void open_outfile()
  143. {
  144.     struct tm *t;
  145.     unsigned long now=time(0L);
  146.     char buf[100];
  147.     t=localtime(&now);
  148.  
  149.     sprintf(buf,"protect.%02d%02d%02d.%02d%02d",
  150.         t->tm_year,
  151.         t->tm_mon+1,
  152.         t->tm_mday,
  153.         t->tm_hour,
  154.         t->tm_min);
  155.     printf(";protectomat dumping to '%s'\n",buf);
  156.     gl.outfile=fopen(buf,"w");
  157.     if(gl.outfile==0)
  158.         fatal_error("can't open output file, (unix errno)",errno);
  159.  
  160.     sprintf(buf,"history.%02d%02",
  161.         t->tm_year,
  162.         t->tm_mon+1);
  163.     printf(";protectomat history log to '%s'\n",buf);
  164.     gl.historyfile=fopen(buf,"a");
  165.     if(gl.historyfile==0)
  166.         fatal_error("can't open history file, (unix errno)",errno);
  167.     fprintf(gl.historyfile,"\nProtecomat starting at %s",ctime(&now));
  168. }
  169.  
  170. /*
  171.  * map a number to text
  172.  */
  173. char *map_num_to_text(char * fname,cache_entry_pt acache,long an_id,int avol,int kind);
  174. char *map_num_to_text(fname,acache,an_id,avol,kind)
  175. char *fname;
  176. register cache_entry_pt acache;
  177. long an_id;
  178. int avol;
  179. int kind;
  180. {
  181.     HParamBlockRec cinfo;
  182.     char xxname[300];
  183.     int os;
  184.     int csize=0;
  185.     while(acache->text[0]!=0) {
  186.         if(acache->num==an_id)
  187.             return &acache->text[1];
  188.         acache++;
  189.         csize++;
  190.     }
  191.  
  192.     if(csize>CACHE_SIZE)
  193.         file_error(fname,"cash size exeeded, recompile protectomat with larger CACHE_SIZE",0);
  194.  
  195.     /*
  196.      * not found so add it
  197.      */
  198.     acache->num=an_id;
  199.     memset(&cinfo,0,sizeof(cinfo));
  200.     cinfo.objParam.ioObjType=kind;
  201.     /*Type here should really be Ptr but File.h has it as ProcPtr*/
  202.     cinfo.objParam.ioObjNamePtr=(ProcPtr)acache->text;
  203.     cinfo.objParam.ioObjID=an_id;
  204.     cinfo.objParam.ioVRefNum=avol;
  205.     xxname[0]=0;
  206.     cinfo.objParam.ioNamePtr=(StringPtr)xxname;
  207.     os=PBHMapID(&cinfo,FALSE);
  208.     if(os!=0) {
  209.         char errbuf[ERR_BUF_SIZE];
  210.         sprintf(errbuf,"error mapping id %ld kind=%d to text PBHMapID\n",an_id,kind);
  211.         file_error(fname,errbuf,os);
  212.     }
  213.     return str_fname(acache->text);
  214. }
  215.  
  216. /*
  217.  * print out a protection in human readable form
  218.  */
  219. char *print_1_prot(char *dst,long prot,char pname);
  220. char *print_1_prot(char *dst,long prot,char pname)
  221. {
  222.     prot&=0x7;        /*only interested in access bits*/
  223.     if(prot==0)        /*if no access no output*/
  224.         return dst;
  225.     *dst++ = pname;
  226.     *dst++ = '(';
  227.     if((prot&4)!=0)
  228.         *dst++ = 'w';
  229.     if((prot&2)!=0)
  230.         *dst++ = 'r';
  231.     if((prot&1)!=0)
  232.         *dst++ = 's';
  233.     *dst++=')';
  234.     return dst;
  235. }
  236.  
  237. /*
  238.  * print out protections in human readable form
  239.  */
  240. void print_prot_names(char *dst,long prot);
  241. void print_prot_names(char *dst,long prot)
  242. {
  243.     dst=print_1_prot(dst,prot,'o');
  244.     dst=print_1_prot(dst,prot>>8,'g');
  245.     dst=print_1_prot(dst,prot>>16,'e');
  246.     *dst=0;
  247. }
  248.  
  249. /*
  250.  * print the protection of one directory
  251.  */
  252. void get_1_dir(char *fname,int avnum,long dir_id,StringPtr aname);
  253. void get_1_dir(fname,avnum,dir_id,aname)
  254. char *fname;
  255. int avnum;
  256. long dir_id;
  257. StringPtr aname;
  258. {
  259.     int os;
  260.     HParamBlockRec cinfo;
  261.     char prot_names[100];
  262.  
  263.     char xxname[300];
  264.     memcpy(xxname,aname,aname[0]&0x0FFL);
  265.  
  266.     memset(&cinfo,0,sizeof(cinfo));
  267.  
  268.     cinfo.accessParam.ioVRefNum=avnum;
  269.     cinfo.accessParam.ioNamePtr=aname;
  270.     cinfo.fileParam.ioDirID=dir_id;
  271.     os=PBHGetDirAccess(&cinfo,FALSE);
  272.     if(os!=0)
  273.         file_error(fname,"can't lookup access",os);
  274.     cinfo.accessParam.ioACAccess&= 0x00FFFFFFL;
  275.     print_prot_names(prot_names,cinfo.accessParam.ioACAccess);
  276.     fprintf(gl.outfile,
  277.         "=%s,%s,%s,%s\n",
  278.         map_num_to_text(fname,user_cache,cinfo.accessParam.ioACOwnerID,avnum,1),
  279.         map_num_to_text(fname,group_cache,cinfo.accessParam.ioACGroupID,avnum,2),
  280.         prot_names,
  281.         fname);
  282. }
  283.  
  284. char *mac_ctime(long atime);
  285. char *mac_ctime(long atime)
  286. {
  287.     static Str255 result;
  288.     Str255 ttime;
  289.     IUDateString(atime,shortDate,result);
  290.     result[(result[0]+1)&0xff]=0;
  291.     IUTimeString(atime,FALSE,ttime);
  292.     ttime[(ttime[0]+1)&0xff]=0;
  293.     strcat((char *)&result[1]," ");
  294.     strcat((char *)&result[1],(char *)&ttime[1]);
  295.     return (char *)&result[1];
  296. }
  297.  
  298. void remember_file_info(CInfoPBPtr cinfo,char *fname);
  299. void remember_file_info(CInfoPBPtr cinfo,char *fname)
  300. {
  301.     register unsigned long mt=cinfo->hFileInfo.ioFlMdDat;
  302.     register unsigned long bt=cinfo->hFileInfo.ioFlBkDat;
  303.     register unsigned long ct=cinfo->hFileInfo.ioFlMdDat;
  304.     if(mt<ct)
  305.         mt=ct;
  306.     if(mt>bt) {
  307.       gl.unbacked_files++;
  308.       gl.bytes_needing_saved+=cinfo->hFileInfo.ioFlLgLen;
  309.       if(mt<gl.oldest_unbacked) {
  310.         gl.oldest_unbacked=mt;
  311. #ifdef DEBUGGING
  312.         fprintf(stdout,"file %s\n",fname);
  313.         fprintf(stdout,"mod time = %s\n",mac_ctime(mt));
  314.         fprintf(stdout,"bak time = %s\n",mac_ctime(bt));
  315.         fprintf(stdout,"dirty %s\n",fname);
  316. #endif
  317.         }
  318.     }
  319. }
  320.  
  321. void warn_desktop(char *fname);
  322. void warn_desktop(char *fname)
  323. {
  324.     fprintf(gl.outfile,";Danger, desktop file found - %s\n",fname);
  325.     fprintf(gl.historyfile,";Danger, desktop file found - %s\n",fname);
  326.     fprintf(stdout,";Danger, desktop file found - %s\n",fname);
  327.     gl.num_desktop_files++;
  328. }
  329.  
  330. /*
  331.  * convert a vnum to text
  332.  */
  333. void scan_dir(char *fname,char *fsuffix,int avnum,long dir_id,int offset);
  334. void scan_dir(fname,fsuffix,avnum,dir_id,offset)
  335. char *fname;
  336. char *fsuffix;
  337. int avnum;
  338. long dir_id;
  339. int offset;
  340. {
  341.     int os;
  342.     CInfoPBRec cinfo;
  343.     char aname[300];
  344.     int findex=offset;
  345.     *fsuffix++ = ':';
  346.     while(TRUE) {
  347.         *fsuffix=0;
  348.         memset(&cinfo,0,sizeof(cinfo));
  349.         aname[0]=0;
  350.         cinfo.hFileInfo.ioVRefNum=avnum;
  351.         cinfo.hFileInfo.ioNamePtr=(StringPtr)aname;
  352.         cinfo.hFileInfo.ioFDirIndex=findex++;
  353.         cinfo.hFileInfo.ioDirID=dir_id;
  354.         os=PBGetCatInfo(&cinfo,FALSE);
  355.         if(os!=0) {
  356.             if(os!= -43)
  357.                 file_error(fname,"can't step to next file",os);
  358.             break;
  359.         }
  360.         strcpy(fsuffix,str_fname(aname));
  361.         if(strcmp(fsuffix,"Desktop")==0)
  362.             warn_desktop(fname);
  363.         if((cinfo.hFileInfo.ioFlAttrib&ioDirMask)==0) {
  364.             gl.num_files++;
  365.             remember_file_info(&cinfo,fname);
  366.             continue;
  367.         }
  368.         gl.num_dirs++;
  369.         get_1_dir(fname,avnum,dir_id,(StringPtr)aname);
  370.         if(cinfo.hFileInfo.ioDirID!=2)
  371.          scan_dir(fname,fsuffix+strlen(fsuffix),avnum,cinfo.hFileInfo.ioDirID,1);
  372.     }
  373. }
  374.  
  375. void log_backup_info(FILE *of,char *vname);
  376. void log_backup_info(FILE *of,char *vname)
  377. {
  378.     unsigned long now;
  379.     long ksaved=((gl.bytes_needing_saved)/1024.0);
  380.     now=time(0L);
  381.     fprintf(of,";volume '%s' contained %ld directories, %ld files %s",
  382.             vname,
  383.             gl.num_dirs,
  384.             gl.num_files,
  385.             ctime(&now));
  386.     if(gl.unbacked_files==0)
  387.       fprintf(of,";volume '%s' allfiles are currently backed up.\n",vname);
  388.     else
  389.       fprintf(of,";volume '%s' had %ld files needing to be backed up.\n"
  390.                          "; oldest dirty file was written on %s\n"
  391.                          "; %ldK data bytes need to be saved\n",
  392.             vname,
  393.             gl.unbacked_files,
  394.             mac_ctime(gl.oldest_unbacked),
  395.             ksaved);
  396. }
  397.  
  398. /*
  399.  * select an input path
  400.  */
  401. void get_source_path(void);
  402. void get_source_path()
  403. {
  404.     FILE *vfile;
  405.     char vname[ERR_BUF_SIZE];
  406.     int vname_len;
  407.     long vol_num;
  408.     open_outfile();
  409.     if((vfile=fopen("volume_list","r"))==0)
  410.         fatal_error("can't open volume_list (errno)",errno);
  411.     while(!read_line(vname,vfile)) {
  412.         unsigned long now;
  413.         now=time(0L);
  414.         gl.num_files=0;
  415.         gl.num_dirs=0;
  416.         gl.oldest_unbacked=NO_OLDEST;
  417.         gl.unbacked_files=0;
  418.         gl.bytes_needing_saved=0.0;
  419.         fprintf(gl.outfile,";dumping volume '%s' at %s",vname,ctime(&now));
  420.         fprintf(gl.historyfile,";dumping volume '%s' at %s",vname,ctime(&now));
  421.         printf(";dumping volume '%s' at %s",vname,ctime(&now));
  422.         vname_len=strlen(vname);
  423.         if((vol_num=get_vol_id(vname))==BAD_VOL_NUM)
  424.             fatal_error("can't map directory id to name",0);
  425.         scan_dir(vname,vname+vname_len,vol_num,ROOT_DIR_ID,0);
  426.         vname[vname_len]=0;
  427.         log_backup_info(gl.outfile,vname);
  428.         log_backup_info(gl.historyfile,vname);
  429.         log_backup_info(stdout,vname);
  430.         if(gl.num_dirs<2)
  431.             fatal_error("volume didn't have any directories",0);
  432.     }
  433.     if(gl.num_desktop_files!=0)
  434.         fatal_error("Desktop files exist on appleshare volumes",0);
  435.     fclose(vfile);
  436. }
  437.  
  438. int main(argc,argv)
  439. int argc;
  440. char **argv;
  441. {
  442.     printf(";pmDump - dump appleshare protections v%d.%d built on %s %s\n",
  443.         VER_MAJ,VER_MIN,__DATE__,__TIME__);
  444.     printf(";send bug reports to Aaron Wohl (aw0g+@andrew.cmu.edu)\n");
  445.     allocate_cache_entries();
  446.     printf(";reading list of volumes to dump from file volume_info\n");
  447.     get_source_path();
  448.     die("Protectomat finished normaly","OK");
  449. }
  450.